/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.launcher3;

import android.content.ComponentName;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.PaintDrawable;
import android.text.Layout;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.util.DisplayMetrics;
import android.view.ViewGroup;

/**
 * Various utilities shared amongst the Launcher's classes.
 */
final class Utilities {
	private static int sIconWidth = -1;
	private static int sIconHeight = -1;
	private static int sItemIconBGWidth = -1;
	private static int sIconTextureWidth = -1;
	private static int sIconTextureHeight = -1;

	static int sColors[] = { 0xffff0000, 0xff00ff00, 0xff0000ff };
	static int sColorIndex = 0;

	private static final Paint sPaint = new Paint();
	private static final Rect sBounds = new Rect();
	private static final Rect sOldBounds = new Rect();
	private static Canvas sCanvas = new Canvas();

//	static final BgMap[] sBgMap;
	static final int[] sRandomIconBg;
	static final int[] sRandom3rdIconBg;
	private static final String TAG = "Utilities";

	static {

		sCanvas.setDrawFilter(new PaintFlagsDrawFilter(Paint.DITHER_FLAG,
				Paint.FILTER_BITMAP_FLAG));
//		sBgMap = BgMapFactory.getBgMap();
		sRandomIconBg = new int[4];
		sRandomIconBg[0] = R.drawable.homescreen_menu_marketbg1;
		sRandomIconBg[1] = R.drawable.homescreen_menu_marketbg2;
		sRandomIconBg[2] = R.drawable.homescreen_menu_marketbg3;
		sRandomIconBg[3] = R.drawable.homescreen_menu_marketbg4;
		
		sRandom3rdIconBg = new int[] {R.drawable.homescreen_menu_marketbg_0,
				R.drawable.homescreen_menu_marketbg_1,
				R.drawable.homescreen_menu_marketbg_2,
				R.drawable.homescreen_menu_marketbg_3,
				R.drawable.homescreen_menu_marketbg_4 };
	}
	
	
	/**
	 * 贺辉增加 2011年10月27日18:41:46
	 */
	static void  reset()
	{
		 sIconWidth = -1;
		 sIconHeight = -1;
	   sItemIconBGWidth = -1;
	}
	
	
	static Drawable getDrawableIconBg(String packageName, String className,
			Context context, boolean systemApp) {
//		Log.e("getDrawableIconBg","packageName "+packageName+"  className  "+className);
			return new ColorDrawable(Color.parseColor("#00ff0000"));
		
//		Resources localResources = context.getResources();
//		int j;
//		if ((systemApp) && (packageName != null)) {
//			j = findResFixedBg(packageName, className);
//
//			if (j == -1) {
//				long l3 = SystemClock.uptimeMillis() % sRandomIconBg.length;
//				return localResources.getDrawable(sRandomIconBg[(int) l3]);
//			} else {
//				return localResources.getDrawable(j);
//
//			}
//		}
//		if (packageName == null) {
//			long l3 = SystemClock.uptimeMillis() % sRandomIconBg.length;
//			j = sRandomIconBg[(int)l3];
//			return localResources.getDrawable(j);
//		}
//		return localResources.getDrawable(sRandom3rdIconBg[packageName.length()
//				% sRandom3rdIconBg.length]);
//		
//		
//		
		
		

	}

//	/**
//	 * 完整.
//	 * 
//	 * @param packageName
//	 * @param className
//	 * @return
//	 */
//	static int findResFixedBg(String packageName, String className) {
//		int j = sBgMap.length;
//		int k = 0;
//		while (k < j) {
//			if (packageName.equals(sBgMap[k].mPackageName)) {
//				if (sBgMap[k].mClassName == null) {
//					return sBgMap[k].mResid;
//				} else {
//					if (className.equals(sBgMap[k].mClassName)) {
//						return sBgMap[k].mResid;
//					}
//				}
//			}
//			k++;
//		}
//		return -1;
//	}
//
//	
	

	/**
	 * Returns a Drawable representing the thumbnail of the specified Drawable.
	 * The size of the thumbnail is defined by the dimension
	 * android.R.dimen.launcher_application_icon_size.
	 * 
	 * This method is not thread-safe and should be invoked on the UI thread
	 * only.
	 * 
	 * @param icon
	 *            The icon to get a thumbnail of.
	 * @param context
	 *            The application's context.
	 * 
	 * @return A thumbnail for the specified icon or the icon itself if the
	 *         thumbnail could not be created.
	 */
	static Drawable createIconThumbnail(Drawable icon, Context context) {
//		Log.e(TAG,"createIconThumbnail Drawable   111");
		final Resources resources = context.getResources();
		if (sIconWidth == -1) {
			
			sIconWidth = sIconHeight = (int) resources
					.getDimension(android.R.dimen.app_icon_size);
		}
		if (sItemIconBGWidth == -1) {
			//final Resources resources = context.getResources();
			sItemIconBGWidth = (int) resources
					.getDimension(R.dimen.menu_item_icon_width);
		}
		
		
//		Log.e(TAG,"sItemIconBGWidth "+sItemIconBGWidth);

		int width = sIconWidth;
		int height = sIconHeight;

		float scale = 1.0f;
		if (icon instanceof PaintDrawable) {
			PaintDrawable painter = (PaintDrawable) icon;
			painter.setIntrinsicWidth(width);
			painter.setIntrinsicHeight(height);
		} else if (icon instanceof BitmapDrawable) {
			// Ensure the bitmap has a density.
			BitmapDrawable bitmapDrawable = (BitmapDrawable) icon;
			Bitmap bitmap = bitmapDrawable.getBitmap();
			if (bitmap.getDensity() == Bitmap.DENSITY_NONE) {
				bitmapDrawable.setTargetDensity(context.getResources()
						.getDisplayMetrics());
			}
		}
		int iconWidth = icon.getIntrinsicWidth();
		int iconHeight = icon.getIntrinsicHeight();
		
		
		

		if (width > 0 && height > 0) {
			if (width < iconWidth || height < iconHeight || scale != 1.0f) {
				final float ratio = (float) iconWidth / iconHeight;

				if (iconWidth > iconHeight) {
					height = (int) (width / ratio);
				} else if (iconHeight > iconWidth) {
					width = (int) (height * ratio);
				}

				final Bitmap.Config c = icon.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
						: Bitmap.Config.RGB_565;
				final Bitmap thumb = Bitmap.createBitmap(sItemIconBGWidth,
						sItemIconBGWidth, c);
				final Canvas canvas = sCanvas;
				canvas.setBitmap(thumb);
				
				Drawable	 bg = getDrawableIconBg(null,null,context ,true);
				
				bg.setBounds(0, 0, context.getResources()
		                .getDimensionPixelSize(R.dimen.menu_item_icon_width), context.getResources()
		                .getDimensionPixelSize(R.dimen.menu_item_icon_width));
				bg.setFilterBitmap(true);
				bg.draw(canvas);
				canvas.save();
				canvas.translate((sItemIconBGWidth-sIconWidth)/2, (sItemIconBGWidth-sIconWidth)/2);
				
//				Log.e(TAG,"createScaledBitmap");
				
				// Copy the old bounds to restore them later
				// If we were to do oldBounds = icon.getBounds(),
				// the call to setBounds() that follows would
				// change the same instance and we would lose the
				// old bounds
				sOldBounds.set(icon.getBounds());
				final int x = (sIconWidth - width) / 2;
				final int y = (sIconHeight - height) / 2;
				icon.setBounds(x, y, x + width, y + height);
				icon.draw(canvas);
				canvas.restore();
				icon.setBounds(sOldBounds);
				icon = new FastBitmapDrawable(thumb);
				return icon;
			} else if (iconWidth < width && iconHeight < height) {
				final Bitmap.Config c = Bitmap.Config.ARGB_8888;
				final Bitmap thumb = Bitmap.createBitmap(sItemIconBGWidth,
						sItemIconBGWidth, c);
				final Canvas canvas = sCanvas;
				canvas.setBitmap(thumb);
				
				
				Drawable	 bg = getDrawableIconBg(null,null,context ,true);
				bg.setBounds(0, 0, sItemIconBGWidth, sItemIconBGWidth);
				bg.setFilterBitmap(true);
				bg.draw(canvas);
					canvas.save();
					canvas.translate((sItemIconBGWidth-sIconWidth)/2, (sItemIconBGWidth-sIconWidth)/2);
//					Log.e(TAG,"createScaledBitmap");
				
				sOldBounds.set(icon.getBounds());
				final int x = (width - iconWidth) / 2;
				final int y = (height - iconHeight) / 2;
				icon.setBounds(x, y, x + iconWidth, y + iconHeight);
				icon.draw(canvas);
				canvas.restore();
				icon.setBounds(sOldBounds);
				icon = new FastBitmapDrawable(thumb);
				return icon;
			}
			else
			{
				if(icon instanceof  BitmapDrawable)
				{
				final Bitmap.Config c = Bitmap.Config.ARGB_8888;
				final Bitmap thumb = Bitmap.createBitmap(sItemIconBGWidth,
						sItemIconBGWidth, c);
				final Canvas canvas = sCanvas;
				canvas.setBitmap(thumb);
				
				Drawable	 bg = getDrawableIconBg(null,null,context ,true);
				bg.setBounds(0, 0, sItemIconBGWidth, sItemIconBGWidth);
				bg.setFilterBitmap(true);
				bg.draw(canvas);
					canvas.save();
					canvas.translate((sItemIconBGWidth-sIconWidth)/2, (sItemIconBGWidth-sIconWidth)/2);
					canvas.drawBitmap(((BitmapDrawable)icon).getBitmap(), 0, 0, null);
					canvas.restore();
					icon = new FastBitmapDrawable(thumb);
					return icon;
				}
				return icon;
			}
		}

		return icon;
	}

	/**
	 * Returns a Bitmap representing the thumbnail of the specified Bitmap. The
	 * size of the thumbnail is defined by the dimension
	 * android.R.dimen.launcher_application_icon_size.
	 * 
	 * This method is not thread-safe and should be invoked on the UI thread
	 * only.
	 * 
	 * @param bitmap
	 *            The bitmap to get a thumbnail of.
	 * @param context
	 *            The application's context.
	 * @param componentName
	 *            TODO
	 * @return A thumbnail for the specified bitmap or the bitmap itself if the
	 *         thumbnail could not be created.
	 */
	static Bitmap createBitmapThumbnail(Bitmap bitmap, Context context, ComponentName componentName) {
//		Log.e(TAG,"createBitmapThumbnail Bitmap ");
		
		if (sIconWidth == -1) {
			final Resources resources = context.getResources();
			sIconWidth = sIconHeight = (int) resources
					.getDimension(android.R.dimen.app_icon_size);
		}

		if (sItemIconBGWidth == -1) {
			final Resources resources = context.getResources();
			sItemIconBGWidth = (int) resources
					.getDimension(R.dimen.menu_item_icon_width);
		}
		
//		Log.e(TAG,"sItemIconBGWidth  1  "+sItemIconBGWidth);
		
		int width = sIconWidth;
		int height = sIconHeight;

		final int bitmapWidth = bitmap.getWidth();
		final int bitmapHeight = bitmap.getHeight();
		Drawable bg=null;
		
		if(componentName != null)
		{
			 bg = getDrawableIconBg(componentName.getPackageName(),componentName.getClassName(),context ,true);
		}
		else
		{
			 bg =getDrawableIconBg(null,null,context ,true);
		}
		
		bg.setBounds(0, 0, sItemIconBGWidth, sItemIconBGWidth);
		
	
		if (width > 0 && height > 0) {
			if (width < bitmapWidth || height < bitmapHeight) {
				final float ratio = (float) bitmapWidth / bitmapHeight;

				if (bitmapWidth > bitmapHeight) {
					height = (int) (width / ratio);
				} else if (bitmapHeight > bitmapWidth) {
					width = (int) (height * ratio);
				}

				 Bitmap.Config c = (width == sIconWidth && height == sIconHeight) ? bitmap
						.getConfig() : Bitmap.Config.ARGB_8888;
						if(c==null)
						{
							c=Bitmap.Config.ARGB_8888;
							
						}
						
				final Bitmap thumb = Bitmap.createBitmap(sItemIconBGWidth,
						sItemIconBGWidth, c);
				final Canvas canvas = sCanvas;
				final Paint paint = sPaint;
				canvas.setBitmap(thumb);
				paint.setDither(false);
				paint.setFilterBitmap(true);
				bg.setFilterBitmap(true);
				bg.setBounds(0, 0, sItemIconBGWidth, sItemIconBGWidth);
				bg.draw(canvas);
				canvas.save();
				canvas.translate((sItemIconBGWidth-sIconWidth)/2, (sItemIconBGWidth-sIconWidth)/2);
				sBounds.set((sIconWidth - width) / 2,
						(sIconHeight - height) / 2, width, height);
				sOldBounds.set(0, 0, bitmapWidth, bitmapHeight);
				canvas.drawBitmap(bitmap, sOldBounds, sBounds, paint);
				canvas.restore();
				return thumb;
			} else if (bitmapWidth < width || bitmapHeight < height) {
				final Bitmap.Config c = Bitmap.Config.ARGB_8888;
				final Bitmap thumb = Bitmap.createBitmap(sItemIconBGWidth,
						sItemIconBGWidth, c);
				final Canvas canvas = sCanvas;
				final Paint paint = sPaint;
				canvas.setBitmap(thumb);
				paint.setDither(false);
				paint.setFilterBitmap(true);
				bg.setFilterBitmap(true);
				bg.draw(canvas);
				canvas.save();
				canvas.translate((sItemIconBGWidth-sIconWidth)/2, (sItemIconBGWidth-sIconWidth)/2);
				canvas.drawBitmap(bitmap, (sIconWidth - bitmapWidth) / 2,
						(sIconHeight - bitmapHeight) / 2, paint);
				canvas.restore();
				return thumb;
			}
		}
		
		final Canvas canvas = sCanvas;
		final Bitmap.Config c = Bitmap.Config.ARGB_8888 ;
		final Bitmap thumb = Bitmap.createBitmap(sItemIconBGWidth,
				sItemIconBGWidth, c);
		final Paint paint = sPaint;
		canvas.setBitmap(thumb);
		paint.setDither(false);
		paint.setFilterBitmap(true);
//		bg.setFilterBitmap(true);
//		bg.setDither(true) ;
		bg.setBounds(0, 0, sItemIconBGWidth, sItemIconBGWidth);
		bg.draw(canvas);
		canvas.save();
		canvas.translate((sItemIconBGWidth-sIconWidth)/2, (sItemIconBGWidth-sIconWidth)/2);
		canvas.drawBitmap(bitmap, 0,0, paint);
		canvas.restore();
//		Log.e(TAG,"createBitmapThumbnail  return bitmap ");
		return thumb;
	}

	public static Bitmap createIconBitmap(Drawable icon, Context context, ComponentName componentName) {
		if (icon instanceof FastBitmapDrawable) {
			FastBitmapDrawable fIcon = (FastBitmapDrawable) icon;
			return Utilities.createBitmapThumbnail(fIcon.getBitmap(), context, componentName);
		}
		return Utilities.createBitmapThumbnail(
				((BitmapDrawable) icon).getBitmap(), context, componentName);
	}

	static void zOrderTweakMoveChild(ViewGroup paramViewGroup, int paramInt1,
			int paramInt2, boolean paramBoolean) {
		if (paramInt1 == paramInt2)
			return;
		int i = paramViewGroup.getChildCount();
		paramViewGroup.getChildAt(paramInt1).bringToFront();
		int j = 0;
		while (true) {
			int k = i - paramInt2 - 1;
			if (j >= k)
				break;
			paramViewGroup.getChildAt(paramInt2).bringToFront();
			j += 1;
		}
		if (paramBoolean) {
			paramViewGroup.requestLayout();
		}
	}

	static int roundToPow2(int paramInt) {
		int i = paramInt;
		paramInt >>= 1;
		int j = 134217728;
		while ((j != 0) && ((paramInt & j) == 0))
			j >>= 1;
		while (j != 0) {
			paramInt |= j;
			j >>= 1;
		}
		paramInt += 1;
		if (paramInt != i)
			paramInt <<= 1;
		return paramInt;
	}

	static class BubbleText {
		private static final int MAX_LINES = 2;
		private final int mBitmapHeight;
		private final int mBitmapWidth;
		private final RectF mBubbleRect;
		private final int mDensity;
		private final int mFirstLineY;
		private final int mLeading;
		private final int mLineHeight;
		private final TextPaint mTextPaint;
		private final float mTextWidth;

		BubbleText(LauncherApplication application) {
			RectF localRectF1 = new RectF();
			this.mBubbleRect = localRectF1;
			Resources localResources = application.getResources();
			DisplayMetrics localDisplayMetrics = localResources
					.getDisplayMetrics();
			float f1 = localDisplayMetrics.density;
			int i = localDisplayMetrics.densityDpi;
			this.mDensity = i;
			float f2 = 2.0F * f1;
			float f3 = 2.0F * f1;
			float f4 = localResources.getDimension(R.dimen.title_texture_width);
			RectF localRectF2 = this.mBubbleRect;
			localRectF2.left = 0.0F;
			localRectF2.top = 0.0F;
			float f5 = (int) f4;
			localRectF2.right = f5;
			float f6 = f4 - f2 - f3;
			this.mTextWidth = f6;
			TextPaint localTextPaint = new TextPaint();
			this.mTextPaint = localTextPaint;
			float f7 = 13.0F * f1;
			localTextPaint.setTextSize(f7);
			localTextPaint.setColor(-1);
			localTextPaint.setAntiAlias(true);
			float f8 = -localTextPaint.ascent();
			float f9 = localTextPaint.descent();
			int j = (int) (0.5F + 0.0F);
			this.mLeading = j;
			int k = (int) (0.0F + f8 + 0.5F);
			this.mFirstLineY = k;
			int m = (int) (0.0F + f8 + f9 + 0.5F);
			this.mLineHeight = m;
			int n = (int) (this.mBubbleRect.width() + 0.5F);
			this.mBitmapWidth = n;
			int i1 = Utilities
					.roundToPow2((int) (this.mLineHeight * 2 + 0.0F + 0.5F));
			this.mBitmapHeight = i1;
			RectF localRectF3 = this.mBubbleRect;
			float f10 = this.mBitmapWidth;
			float f11 = this.mBubbleRect.width();
			float f12 = (f10 - f11) / 2.0F;
			localRectF3.offsetTo(f12, 0.0F);
		}

		private int height(int paramInt) {
			int i = this.mLineHeight * paramInt;
			int j = this.mLeading;
			int k = i + j;
			int m = this.mLeading;
			return (int) (k + m + 0.0F);
		}

		Bitmap createTextBitmap(String paramString) {
			int i = this.mBitmapWidth;
			int j = this.mBitmapHeight;
			Bitmap.Config localConfig = Bitmap.Config.ALPHA_8;
			Bitmap localBitmap = Bitmap.createBitmap(i, j, localConfig);
			int k = this.mDensity;
			localBitmap.setDensity(k);
			Canvas localCanvas = new Canvas(localBitmap);
			TextPaint localTextPaint1 = this.mTextPaint;
			int m = (int) this.mTextWidth;
			Layout.Alignment localAlignment = Layout.Alignment.ALIGN_CENTER;
			String str1 = paramString;
			StaticLayout localStaticLayout = new StaticLayout(str1,
					localTextPaint1, m, localAlignment, 1.0F, 0.0F, true);
			int n = localStaticLayout.getLineCount();
			if (n > 2)
				n = 2;
			int i1 = 0;
			while (i1 < n) {
				int i2 = localStaticLayout.getLineStart(i1);
				int i3 = localStaticLayout.getLineEnd(i1);
				String str2 = paramString;
				int i4 = i2;
				int i5 = i3;
				String str3 = str2.substring(i4, i5);
				float f1 = this.mBubbleRect.left;
				float f2 = this.mBubbleRect.width();
				float f3 = this.mTextPaint.measureText(str3);
				float f4 = (f2 - f3) * 0.5F;
				int i6 = (int) (f1 + f4);
				int i7 = this.mFirstLineY;
				int i8 = this.mLineHeight * i1;
				int i9 = i7 + i8;
				float f5 = i6;
				float f6 = i9;
				TextPaint localTextPaint2 = this.mTextPaint;
				localCanvas.drawText(str3, f5, f6, localTextPaint2);
				i1++;
			}
			return localBitmap;
		}

		int getBitmapHeight() {
			return this.mBitmapHeight;
		}

		int getBitmapWidth() {
			return this.mBitmapWidth;
		}

		int getBubbleWidth() {
			return (int) (this.mBubbleRect.width() + 0.5F);
		}

		int getMaxBubbleHeight() {
			return height(2);
		}
	}

}
